home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / NextAnswers / PeopleDemo_sybase / MainController.m < prev    next >
Text File  |  1994-06-24  |  7KB  |  276 lines

  1. /* MainController.m
  2.  * You may freely copy, distribute, and reuse the code in this example.
  3.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  4.  * fitness for any particular use.
  5.  *
  6.  * Written by Mai Nguyen, NeXT Developer Support
  7.  
  8.  */
  9.  
  10. #import "MainController.h"
  11. #import "Department.h"
  12. #import "strings.h"
  13.  
  14. @implementation MainController
  15.  
  16. - init
  17. {
  18.     [super init];
  19.     return self;
  20. }
  21.  
  22. - appDidInit:sender
  23. {
  24.     dbDataSource = [masterController dataSource];
  25.     dbChannel = [dbDataSource databaseChannel];
  26.     adaptorChannel = [dbChannel adaptorChannel];
  27.     rootEntity = [dbDataSource entity];
  28.     
  29.     [self setDelegates];
  30.     [self fetch:sender];    
  31.     return self;
  32. }
  33.  
  34. /* Perform a fetch based on the latest options specified by user. */
  35.  
  36. - fetch:sender
  37. {
  38.     if (optionsPanel)
  39.         [optionsPanel orderOut:sender];
  40.         
  41.     [self setUpFetch:sender];
  42.  
  43.     [masterController fetch];
  44.     return self;
  45. }
  46.  
  47. - newRecord:sender
  48. {
  49.     int i;
  50.     
  51.     /* Clear all the current values in the form cells to prepare
  52.      * for the insertion of a new record.
  53.      */
  54.      for (i = 0; i < 5; i++)
  55.         [formMatrix setStringValue:"" at:i];
  56.     return self;
  57. }
  58.  
  59. - insert:sender
  60. {
  61.     /* Disable the INSERT Button if the input is not valid */
  62.     if ([self validateRecord] == NO) {
  63.         [insertButton setState:0];
  64.         NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
  65.     }
  66.     else {
  67.         [insertButton setState:1];
  68.         [masterController insert:sender];
  69.     }
  70.     return self;
  71. }
  72.  
  73.  
  74. /* Set up the fetch order and specify a qualifier 
  75.  *  for the master table "Department" 
  76.  */
  77. - setUpFetch:sender
  78.     const char    *inputString;
  79.     const char    *attrName = NULL;
  80.     EOQualifier *aQualifier;
  81.     id             fetchOrder;
  82.     id             sortAttribute;
  83.     int             orderType;
  84.  
  85.     /* build the qualifier.
  86.        If the input string is empty, fetch all records.
  87.      */
  88.     inputString = [(TextField *)textField stringValue];
  89.      
  90.     if (inputString == NULL)
  91.         [dbDataSource setQualifier: [rootEntity qualifier]];
  92.     else {
  93.          aQualifier = [[[EOQualifier alloc] initWithEntity:rootEntity
  94.                         qualifierFormat:@"%A >= %d", @"DeptId", 
  95.                         [textField intValue]] autorelease];
  96.         [dbDataSource setQualifier:aQualifier];
  97.          }
  98.                                                      
  99.     /* build the fetch order based on the first column of the master
  100.      * tableview
  101.      */
  102.     orderType = [sortMatrix selectedTag];
  103.     attrName  = [[masterTableview columnAt:0] title];
  104.     sortAttribute = [rootEntity attributeNamed:[ [[NSString alloc]
  105.                                 initWithCString:attrName] autorelease]];
  106.     fetchOrder = [NSArray arrayWithObject:[[[EOAttributeOrdering alloc]
  107.          initWithAttribute:sortAttribute ordering: orderType] autorelease]];
  108.              
  109.     [dbDataSource setFetchOrder:fetchOrder];
  110.        return self;
  111. }
  112.  
  113.  
  114. - (BOOL) validateRecord
  115. {
  116.     int newId, newLocation;
  117.     BOOL result = YES;
  118.     
  119.     newId = [formMatrix intValueAt:0];
  120.     newLocation = [formMatrix intValueAt:2];
  121.     
  122.     /* Do validation here */
  123.     if ( newId < 100 || newId > 999) {
  124.         NXRunAlertPanel(NULL, ERR_INVALID_ID, NULL, NULL, NULL);
  125.         result = NO;
  126.     }
  127.     if ( newLocation != 1101 && newLocation != 1103
  128.             && newLocation != 1104 && newLocation != 1106
  129.             && newLocation != 1207) {
  130.         NXRunAlertPanel(NULL, ERR_INVALID_LOCATION, NULL, NULL, NULL);
  131.         result = NO;
  132.     } 
  133.     return result;
  134.      
  135. }
  136. - setDelegates
  137. {
  138. #ifdef DEBUG     
  139.     [adaptorChannel setDebugEnabled:YES];
  140. #endif 
  141.     [adaptorChannel setDelegate:self];
  142.     [(EOController *) masterController setDelegate:self];
  143.     
  144.     return self;
  145. }
  146.  
  147. @end
  148.  
  149. @implementation MainController (EOAdaptorDelegation)
  150. /* This method is useful to trace SQL queries */
  151.  
  152. - (void)adaptorChannel:channel
  153.     didEvaluateExpression:(NSString *)expression
  154. {
  155.     if (sqlPanel) {
  156.         [text appendToText:"SQL Query:\n"];
  157.         [text appendToText:[expression cString]];
  158.         [text appendToText:"\n"];
  159.     }
  160. }
  161. @end
  162.  
  163.  
  164. @implementation MainController (EOControllerDelegation)
  165.  
  166. /* This method is called before each update. Since the controller has
  167.  * buffer edits turned ON, this method is called when the user explicitly
  168.  * presses the UPDATE button. 
  169.  */
  170. - (NSDictionary *)controller:(EOController *)controller 
  171.                         willSave: (NSDictionary *)edits object:object
  172. {
  173.     if ([self validateRecord] == YES)
  174.             return edits;
  175.     else {
  176.         NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL);
  177.         return nil;
  178.     }
  179. }
  180.  
  181. /* Take the input from the formcells and create a new record */
  182.  
  183. - (BOOL)controller:controller willInsertObject:object inDataSource:dataSource;
  184. {
  185.     [object setDeptId:[NSNumber numberWithInt:[formMatrix intValueAt:0]]];
  186.     [object setDepartmentName:[[[NSString alloc] initWithCString: 
  187.                     [formMatrix stringValueAt:1]] autorelease]];
  188.     [object setLocationId:[NSNumber numberWithInt:
  189.                                         [formMatrix intValueAt:2]]];
  190.         /* The to-many relationship points to an empty autoreleased array */
  191.     [object setToEmployee:[NSArray array]];
  192.     return YES;
  193.     
  194. }
  195.  
  196. /* After insertion, refetch object so that the derived attributes are 
  197.  * properly redisplayed.
  198.  */
  199. - (void)controller:(EOController *)controller didInsertObject:object
  200.     inDataSource:dataSource
  201. {
  202.     [dbChannel refetchObject:object];
  203. }
  204.  
  205. /* After an update, refetch object so that the derived attributes are 
  206.  * properly redisplayed.
  207.  */
  208. - (void)controller:(EOController *)controller didUpdateObject:object
  209.     inDataSource:dataSource
  210. {
  211.     [dbChannel refetchObject:object];
  212. }    
  213.  
  214. /* When the insert operation failed, remove the wrong record and rollback
  215.  * the data source. A failure usually happens when trying to insert a duplicate
  216.  * key.
  217.  */
  218. - (EODataSourceFailureResponse)controller:(EOController *)controller
  219.     failedToInsertObject:object
  220.     inDataSource:dataSource;
  221. {
  222.     NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL);
  223.  
  224.     [controller deleteObjectAtIndex:[masterTableview selectedRow]];
  225.     
  226.     return EORollbackDataSourceFailureResponse;
  227. }
  228.  
  229. /* When deleting a department, we need to null all the references 
  230.  * to that department. Therefore, the "toEmployee" relationship is
  231.  * used to find the employee records attached to a given department.
  232.  * All department ids will then be nulled out.
  233.  */ 
  234.  
  235. - (BOOL)controller:controller willDeleteObject:object
  236. {
  237.     
  238.     NSArray *employeeArray = [object toEmployee];
  239.     NSEnumerator *enumerator = [employeeArray objectEnumerator];
  240.     EOGenericRecord    *employee;
  241.     
  242.     while(employee = [enumerator nextObject]) {
  243.         [employee setObject:[EONull null] forKey:@"DeptId"];
  244.         [(id)[controller dataSource] updateObject:employee];
  245.     }
  246.  
  247.     return YES;
  248. }
  249.  
  250.  
  251. /* Implementing this delegate method allows the controller to discard
  252.  * pending edits. In this example, pending edits are edits rejected by
  253.  * the validation mechanism, hence they can be discarded.
  254.  */
  255. - (BOOL) controllerWillDiscardEdits:(EOController *)controller
  256. {
  257.     return YES;
  258. }
  259.     
  260. @end
  261.  
  262. @implementation Text(printResults)
  263.  
  264. - appendToText:(const char *)newText
  265. {
  266.     int currentLength = [self textLength];
  267.  
  268.     [self setSel:currentLength :currentLength];
  269.     [self replaceSel:newText];
  270.     [self scrollSelToVisible];
  271.     return self;
  272. }
  273.  
  274. @end
  275.